from blog.utils import resize_image
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager as AuthUserManager
from django.core.mail import send_mail
from django.db import models
from django.template.loader import get_template
from django.urls import reverse
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from .tasks import send_active_mail


class UserManager(AuthUserManager):
    def _create_user(self, username, email, password, **extra_fields):
        """
        Create and save a user with the given username, email, and password.
        """
        if not username:
            raise ValueError('The given username must be set')
        # 邮箱也是必须的
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user


class User(AbstractUser):
    """
    自定制用户模型，实现用户邮箱进行登录
    """
    email = models.EmailField('邮箱', unique=True, blank=False)

    USERNAME_FIELD = 'email'
    # 使用createsuperuser管理命令的时候需要填写的字段
    REQUIRED_FIELDS = ['username']  # USERNAME_FILED不能包含在其中，否则报错

    # mobile = models.CharField(max_length=11, blank=True, null=True)

    objects = UserManager()  # 改变用户管理器需要重新迁移，否则报错

    def get_active_token(self):
        """根据用户ID，生成注册激活口令"""
        serializer = Serializer(settings.SECRET_KEY, expires_in=settings.TOKEN_EXPIRES)
        return serializer.dumps({'user_id': self.pk}).decode()

    def send_active_mail(self):
        """发送激活邮件"""
        token = self.get_active_token()
        send_active_mail(self.username, [self.email], token)


def upload_location(instance, filename):
    return f'profile/avatar/{instance.user.id}/{filename}'


class Profile(models.Model):
    # nick_name = models.CharField('昵称', max_length=32)
    user = models.OneToOneField(User, verbose_name='用户', on_delete=models.CASCADE)
    # pipenv install Pillow
    avatar = models.ImageField('个人头像', default='default.jpg', upload_to=upload_location)

    class Meta:
        verbose_name = verbose_name_plural = '个人主页'

    def __str__(self):
        return f'{self.user!s}主页'

    # 重写save方法，更改保存图片的大小
    def save(self, *a, **kw):
        super().save(*a, **kw)

        # 更改用户上传图片大小，个人头像可能为空
        if self.avatar:
            resize_image(self.avatar)
